package com.lnking.lnkingplace.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.util.StringUtil;
import com.lnking.common.http.ReturnResult;
import com.lnking.lnkingplace.model.dto.user.UserDto;
import com.lnking.lnkingplace.model.entity.*;
import com.lnking.lnkingplace.model.enums.UserType;
import com.lnking.lnkingplace.model.login.LoginCompareRequest;
import com.lnking.lnkingplace.model.login.LoginRequest;
import com.lnking.lnkingplace.model.login.PasswordRequest;
import com.lnking.lnkingplace.model.login.SmsLoginRequest;
import com.lnking.lnkingplace.service.*;
import com.lnking.redis.server.RedisServer;
import com.lnking.user.utils.JWTUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author sn
 * @date 2022/7/14
 * @description
 */
@Service
public class LoginServiceImpl implements ILoginService {

    @Autowired
    RedisServer redisServer;

    @Autowired
    IUserService userService;

    @Autowired
    IPlaceInfoService placeInfoService;

    @Autowired
    ILeadersService leadersService;

    @Autowired
    IIsolationPersonnelService isolationPersonnelService;

    @Autowired
    IIsolationPlaceService iIsolationPlaceService;

    @Resource
    IIsolationWorkerService iIsolationWorkerService;

    @Autowired
    IMessageService messageService;


    /**
     * 初始密码
     */
    final String PWD ="123456";

    /**
     * 特殊符号
     */
    public static final String REG_EX ="[\n`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。， 、？]";

    @Override
    public ReturnResult login(LoginRequest params) throws Exception {
        String digestPassword = DigestUtils.sha1Hex(params.getPassword());
        Assert.isTrue(!"".equals(params.getUsername()),"用户名及密码不能为空");
        Assert.isTrue(!"".equals(params.getPassword()),"用户名及密码不能为空");
        String token = JWTUtil.sign(params.getUsername(), params.getPassword());
        // 把用户信息写入redis
        UserDto userDto = new UserDto();
        // 从用户表查询
        User user = userService.getUserByName(params.getUsername());
        // 从监管里面查询
        if (user == null) {
        Leaders leader = leadersService.getLeaderByName(params.getUsername());
        if(leader !=null){
            Assert.notNull(leader, ReturnResult.ResultStatus.USERNAME_NOT_FOUND.getDesc());
            Assert.isTrue(digestPassword.equals(leader.getPassword()), ReturnResult.ResultStatus.BAD_CREDENTIALS.getDesc());
            BeanUtils.copyProperties(leader, userDto);
            userDto.setDesensitizationPhone(leader.getPhone());
        }else{

          // 隔离人员登录
            IsolationPersonnel isolationByName = isolationPersonnelService.getIsolationByName(params.getUsername());
            if(isolationByName!=null){
                Assert.isTrue(digestPassword.equals(isolationByName.getPassword()), ReturnResult.ResultStatus.BAD_CREDENTIALS.getDesc());
                BeanUtils.copyProperties(isolationByName, userDto);
                userDto.setType("隔离人员");
//                IsolationPlace byId = iIsolationPlaceService.getById(isolationByName.getPlaceId());
//                userDto.setPlaceName(byId.getPlaceName());
                userDto.setDesensitizationPhone(isolationByName.getPhone());
            }else{
                IsolationWorker workeByName = iIsolationWorkerService.getWorkeByName(params.getUsername());
                if(workeByName!=null){
                    Assert.isTrue(digestPassword.equals(workeByName.getPassword()), ReturnResult.ResultStatus.BAD_CREDENTIALS.getDesc());
                    BeanUtils.copyProperties(workeByName, userDto);
                    userDto.setType(workeByName.getCamp());
                    IsolationPlace byId = iIsolationPlaceService.getById(workeByName.getPlaceId());
                    userDto.setPlaceName(byId.getPlaceName());
                    userDto.setName(workeByName.getWorkerName());
                    userDto.setPhone(workeByName.getWorkerPhone());
                    userDto.setDesensitizationPhone(workeByName.getWorkerPhone());
                }else {
                    Assert.notNull(isolationByName, ReturnResult.ResultStatus.USERNAME_NOT_FOUND.getDesc());
                }

            }

        }
        }else{
            Assert.isTrue(digestPassword.equals(user.getPassword()), ReturnResult.ResultStatus.BAD_CREDENTIALS.getDesc());
            BeanUtils.copyProperties(user, userDto);
            userDto.setDesensitizationPhone(user.getPhone());
        }


        redisServer.set(token, JSONObject.toJSONString(userDto));

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("token", token);
        resultMap.put("userInfo", userDto);
        return ReturnResult.success("登录成功", resultMap);
    }

    @Override
    public void find(LoginCompareRequest params) {
        // 获取场所名称（去除特殊符号）
        List<PlaceInfo> list = placeInfoService.list();
        PlaceInfo place = null;
        String placeName1 = params.getPlaceName().replaceAll(REG_EX, "");
        for (PlaceInfo placeInfo : list) {
            String placeName = placeInfo.getPlaceName().replaceAll(REG_EX, "");
            if (placeName.equals(placeName1)) {
                place = placeInfo;
                break;
            }
        }
        Assert.notNull(place,"输入场所名字错误");

        // 查询场所是否被注册
        QueryWrapper<User> wapper=new QueryWrapper<>();
        wapper.lambda().eq(User::getPlaceId,place.getId());
        wapper.lambda().eq(User::getType, UserType.LOCATION);
        wapper.lambda().eq(User::getDelFlag,false);
        User user1 = userService.getBaseMapper().selectOne(wapper);
        Assert.isNull(user1,"该场所已有负责人");

        // 新增登录账号
        //场所联系人
        String linkman = params.getUserName();
        //联系电话
        String phoneNumber = params.getPhone();
        User user = new User();
        user.setName(linkman);
        user.setPhone(phoneNumber);
        QueryWrapper<User> wapper1 = new QueryWrapper<>();
        wapper1.lambda().eq(User::getPhone, params.getPhone());
        Integer integer = userService.getBaseMapper().selectCount(wapper1);
        Assert.isTrue(integer == 0, "手机号码不能重复");
        user.setPassword(DigestUtils.sha1Hex(PWD));
        user.setType(UserType.LOCATION);
        user.setPlaceId(place.getId());
        user.setChannel(place.getChannel());
        user.setCreatorTime(LocalDateTime.now());
        userService.getBaseMapper().insert(user);
        // 修改场所负责人
        place.setLinkman(linkman);
        place.setLinkmanPhone(phoneNumber);
        placeInfoService.getBaseMapper().updateById(place);
    }

    @Override
    public ReturnResult smsLogin(SmsLoginRequest params) {
        smsPhone(params);

        String token = JWTUtil.sign(params.getUsername(), params.getCode());
        // 把用户信息写入redis
        UserDto userDto = new UserDto();
        // 从用户表查询
        User user = userService.getUserByName(params.getUsername());




        // 从监管里面查询
        if (user == null) {
            Leaders leader = leadersService.getLeaderByName(params.getUsername());
            if(leader !=null){
                Assert.notNull(leader, ReturnResult.ResultStatus.USERNAME_NOT_FOUND.getDesc());
                BeanUtils.copyProperties(leader, userDto);
                userDto.setDesensitizationPhone(leader.getPhone());
            }else{

                // 隔离人员登录
                IsolationPersonnel isolationByName = isolationPersonnelService.getIsolationByName(params.getUsername());
                if(isolationByName!=null){
                    BeanUtils.copyProperties(isolationByName, userDto);
                    userDto.setType("隔离人员");
                    IsolationPlace byId = iIsolationPlaceService.getById(isolationByName.getPlaceId());
                    userDto.setPlaceName(byId.getPlaceName());
                    userDto.setDesensitizationPhone(isolationByName.getPhone());
                }else{
                    IsolationWorker workeByName = iIsolationWorkerService.getWorkeByName(params.getUsername());
                    if(workeByName!=null){
                        BeanUtils.copyProperties(workeByName, userDto);
                        userDto.setType(workeByName.getCamp());
                        IsolationPlace byId = iIsolationPlaceService.getById(workeByName.getPlaceId());
                        userDto.setPlaceName(byId.getPlaceName());
                        userDto.setName(workeByName.getWorkerName());
                        userDto.setPhone(workeByName.getWorkerPhone());
                        userDto.setDesensitizationPhone(workeByName.getWorkerPhone());
                    }else {
                        Assert.notNull(isolationByName, ReturnResult.ResultStatus.USERNAME_NOT_FOUND.getDesc());
                    }

                }

            }
        }else{
            BeanUtils.copyProperties(user, userDto);
            userDto.setDesensitizationPhone(user.getPhone());
        }

        redisServer.set(token, JSONObject.toJSONString(userDto));

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("token", token);
        resultMap.put("userInfo", userDto);
        return ReturnResult.success("登录成功", resultMap);
    }

    @Override
    public ReturnResult smsPhone(SmsLoginRequest params) {
        String code = DigestUtils.sha1Hex(params.getCode());
        Message message = messageService.phone(params.getUsername());
        Assert.notNull(message,"未查询到验证码");
        Assert.isTrue(code.equals(message.getCode()), "请重新获取验证码");
        Duration duration = Duration.between(message.getCreateTime(),LocalDateTime.now());
        Assert.isTrue((duration.toMinutes()<5), "验证码时间已经超过了5分钟请重新发送");
        return ReturnResult.success("验证码正确");
    }

    @Override
    public void setPassword(PasswordRequest params) {
        SmsLoginRequest smsLoginRequest =new SmsLoginRequest();
        BeanUtils.copyProperties(params,smsLoginRequest);
        smsPhone(smsLoginRequest);
        User userEntity = userService.getUserByName(params.getUsername());
        if (userEntity == null) {
            Leaders leader = leadersService.getLeaderByName(params.getUsername());
            if(leader != null){
                Leaders leaders = new Leaders();
                leaders.setId(leader.getId());
                leaders.setPassword(DigestUtils.sha1Hex(params.getPassword()));
                leadersService.updateById(leaders);
            }else{
                IsolationPersonnel isolationByName = isolationPersonnelService.getIsolationByName(params.getUsername());
                if(isolationByName !=null){
                    IsolationPersonnel isolationPersonnel = new IsolationPersonnel();
                    isolationPersonnel.setId(isolationByName.getId());
                    isolationPersonnel.setPassword(DigestUtils.sha1Hex(params.getPassword()));
                    isolationPersonnelService.updateById(isolationPersonnel);
                }else{
                    IsolationWorker isolationWorker = iIsolationWorkerService.getWorkeByName(params.getUsername());
                    if(isolationWorker !=null){
                        IsolationWorker worker = new IsolationWorker();
                        worker.setId(isolationWorker.getId());
                        worker.setPassword(DigestUtils.sha1Hex(params.getPassword()));
                        iIsolationWorkerService.updateById(worker);
                    }
                }

            }
        } else {
            User user = new User();
            user.setId(userEntity.getId());
            user.setPassword(DigestUtils.sha1Hex(params.getPassword()));
            userService.updateById(user);
    }
    }

}
